#pragma once

#include <vector>
#include <unordered_map>

#include "noncopyable.h"
#include "Timestamp.h"

class Channel;
class EventLoop;

/**
 * muduo库中多路事件分发器的核心IO复用模块
 * Poller 的工作流程
 * 初始化：
 * 创建 Poller 对象，并将其绑定到一个 EventLoop。
 * 初始化 channels_ 映射表。
 * 事件循环：
 * 在 EventLoop 的主循环中，调用 Poller::poll 方法等待事件。
 * poll 方法通过底层的 I/O 复用机制（如 epoll_wait）检测发生事件的文件描述符。
 * 事件分发：
 * poll 方法返回后，将发生事件的文件描述符及其事件类型存储到 activeChannels 列表中。
 * 遍历 activeChannels，调用每个 Channel 的 handleEvent 方法处理事件。
 * 动态管理：
 * 通过 updateChannel 和 removeChannel 方法，动态添加、修改或移除文件描述符的监听状态。
 */
class Poller
{
public:
    using ChannelList = std::vector<Channel *>;

    Poller(EventLoop *loop);
    virtual ~Poller() = default;

    // 给所有IO复用保留统一的接口
    /**
     * poll 方法：
     * 负责调用底层的 I/O 复用机制（如 epoll_wait），等待文件描述符上的事件。
     * 参数：
     * timeoutMs：超时时间（毫秒）。
     * activeChannels：一个 ChannelList，用于存储发生事件的 Channel 对象。
     * 返回值：返回事件发生的时间戳（Timestamp）。
     **/
    virtual Timestamp poll(int timeoutMs, ChannelList *activeChannels) = 0;

    // 负责更新 Poller 中的 Channel 状态（如注册新的文件描述符或修改监听的事件类型）。
    virtual void updateChannel(Channel *channel) = 0;
    // 负责从 Poller 中移除某个 Channel
    virtual void removeChannel(Channel *channel) = 0;

    // 判断参数channel是否在当前的Poller当中
    bool hasChannel(Channel *channel) const;

    // EventLoop可以通过该接口获取默认的IO复用的具体实现
    static Poller *newDefaultPoller(EventLoop *loop);

protected:
    // map的key:sockfd value:sockfd所属的channel通道类型
    using ChannelMap = std::unordered_map<int, Channel *>;
    ChannelMap channels_;

private:
    EventLoop *ownerLoop_; // 定义Poller所属的事件循环EventLoop
};